package com.suxin.data.consumer;

import com.suxin.data.filter.DataFilter;
import com.suxin.data.filter.DataFilterChain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Tang
 * @classname AbstractDataConsumer
 * @description [  ]
 * @date 2021/12/2 16:00
 */
@Slf4j
public abstract class AbstractDataConsumer<T> implements DataConsumer<T> {

    private ThreadPoolExecutor threadPoolExecutor;

    private DataFilterChain dataFilterChain;

    public AbstractDataConsumer(int corePoolSize, int maximumPoolSize, String prefix) {
        this(corePoolSize, maximumPoolSize, 60, prefix);
    }

    public AbstractDataConsumer(int corePoolSize, int maximumPoolSize, Integer queueSize, String prefix) {
        this.threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(queueSize), new CustomizableThreadFactory(prefix));
    }

    @Override
    public void consumer(T data) {
        this.threadPoolExecutor.execute(() -> {
            try {
                T result = data;
                // 先走一遍过滤链
                if (dataFilterChain != null) {
                    result = (T)dataFilterChain.doFilterChain(data);
                    asyncConsumer(result);
                    return;
                }
                asyncConsumer(result);
            } catch (Exception e) {
                log.error("出现错误的数据是:{}",data);
            }
        });
    }

    /**
     * 异步consumer
     * @param data
     */
    protected abstract void asyncConsumer(T data);

}